"""Shared repository helpers for synchronous database operations.

IMPORTANT: 本项目统一使用同步Session，不使用AsyncSession
"""

from __future__ import annotations

from typing import Any, Generic, TypeVar, Type

from sqlalchemy.orm import Session
from pydantic import BaseModel

ModelType = TypeVar("ModelType")
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)


class Repository(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
    """
    Base repository with common CRUD operations (Synchronous).

    统一同步模式Repository，提供标准CRUD操作。
    所有子Repository应继承此类并扩展特定业务方法。
    """

    def __init__(self, model: Type[ModelType], session: Session) -> None:
        self.model = model
        self.session = session

    def get(self, id: Any) -> ModelType | None:
        """Get a single record by ID."""
        return self.session.query(self.model).filter(getattr(self.model, "id") == id).first()

    def list(self, skip: int = 0, limit: int = 100) -> list[ModelType]:
        """Get a list of records with pagination."""
        return self.session.query(self.model).offset(skip).limit(limit).all()

    def create(self, obj_in: CreateSchemaType) -> ModelType:
        """Create a new record."""
        obj_data = obj_in.model_dump()
        db_obj = self.model(**obj_data)
        self.session.add(db_obj)
        self.session.flush()
        self.session.refresh(db_obj)
        return db_obj

    def update(self, db_obj: ModelType, obj_in: UpdateSchemaType | dict[str, Any]) -> ModelType:
        """Update an existing record."""
        if isinstance(obj_in, dict):
            update_data = obj_in
        else:
            update_data = obj_in.model_dump(exclude_unset=True)

        for field, value in update_data.items():
            if hasattr(db_obj, field):
                setattr(db_obj, field, value)

        self.session.flush()
        self.session.refresh(db_obj)
        return db_obj

    def delete(self, id: Any) -> bool:
        """Delete a record by ID."""
        db_obj = self.get(id)
        if db_obj:
            self.session.delete(db_obj)
            self.session.flush()
            return True
        return False

    def save(self, instance: ModelType) -> ModelType:
        """Save an instance (add + flush + refresh)."""
        self.session.add(instance)
        self.session.flush()
        self.session.refresh(instance)
        return instance


# 向后兼容别名
BaseRepository = Repository
